//
// Created by LiuYou on 2021/5/19.
//

#include <cstdlib>
#include <unistd.h>
#include <cstdio>

/*
 * 需要进行201个计算任务, 我使用201个子进程来计算这201个计算任务, 而不使用for循环了。
 *
 * TODO 注意: 此时使用time ./a.out > dev/null 观察时间发现:
 *  子进程的要快很多, for循环的要慢。
 *  我的设备是双核64位, for循环只用了一个核来处理, 子进程是使用2个核来跑(但是子进程会涉及到进程调度), 但是结果
 *  还是子进程的快。其实是跟CPU的进程调度算法关系很大！！！！
 *  慢在创建进程需要时间，快在进程多分的时间片多，总体变快! 这句话来自网络。
 *
 */
int main() {
    const int LEFT = 30000000;
//    const int RIGHT = 30000200;
    const int RIGHT = 30000200;
    int mark{};
    for (int i = LEFT; i <= RIGHT; ++i) {
        // 父进程会回到这里继续fork, 而子进程会在if逻辑中正常返回。
        pid_t pid = fork();


        if (pid < 0) {
            std::perror("fork()");
            std::exit(1);
        } else if (pid == 0) {
            // 子进程
            mark = 1;
            for (int j = 2; j < i / 2; ++j) {
                if (i % j == 0) {
                    mark = 0;
                    break;
                }
            }
            if (mark == 1) {
                std::fprintf(stdout, "%d is prime number.\n", i);
            }
            // 使用sleep这里会产生孤儿进程。
//            sleep(1000);

            // 执行完自己的任务后, 子进程正常退出。
            // 让子进程正常结束, 如果没有下面这行代码, 子进程也会去fork。
            std::exit(0);
        } else {
            // 父进程
            // 父进程在这个if-else逻辑中, 什么也不做, 然后继续去for-i循环中fork子进程。
        }

    }

    // 使用sleep会产生zombie进程。
//    sleep(1000);
    std::exit(0);
}